package cn.ycc1.mymiddle.chat;

import com.alibaba.cloud.ai.dashscope.api.DashScopeApi;
import com.alibaba.cloud.ai.dashscope.chat.DashScopeChatModel;
import dev.langchain4j.model.openai.OpenAiChatModel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.client.advisor.MessageChatMemoryAdvisor;
import org.springframework.ai.chat.memory.ChatMemory;
import org.springframework.ai.chat.memory.InMemoryChatMemory;
import org.springframework.ai.chat.model.ChatModel;
import org.springframework.ai.chat.model.ChatResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.UUID;

import static org.springframework.ai.chat.client.advisor.AbstractChatMemoryAdvisor.CHAT_MEMORY_CONVERSATION_ID_KEY;
import static org.springframework.ai.chat.client.advisor.AbstractChatMemoryAdvisor.CHAT_MEMORY_RETRIEVE_SIZE_KEY;

/**
 * @author ycc
 * @date 2025/5/1
 * 对话记忆介绍
 * ”大模型的对话记忆”这一概念，根植于人工智能与自然语言处理领域，特别是针对具有深度学习能力的大型语言模型而言，
 * 它指的是模型在与用户进行交互式对话过程中，能够追踪、理解并利用先前对话上下文的能力。
 * 此机制使得大模型不仅能够响应即时的输入请求，还能基于之前的交流内容能够在对话中记住先前的对话内容，并根据这些信息进行后续的响应。
 * 这种记忆机制使得模型能够在对话中持续跟踪和理解用户的意图和上下文，从而实现更自然和连贯的对话。
 */
@RestController
@RequestMapping("/chat-memory")
public class ChatMemoryController {
    // 定义 logger（推荐用当前类名作为 logger 名称）
    private static final Logger logger = LoggerFactory.getLogger(ChatMemoryController.class);

    //初始化基于内存的对话记忆
//    private final ChatModel chatModel;
    private final ChatClient chatClient;
    private final ChatMemory chatMemory = new InMemoryChatMemory();

    // 通过构造函数注入（推荐）
    @Autowired
    public ChatMemoryController(ChatModel chatModel) {
//        this.chatModel = chatModel;
        this.chatClient = ChatClient.builder(chatModel)
                .defaultAdvisors(new MessageChatMemoryAdvisor(chatMemory))
                .build();
    }

    @RequestMapping("/chat")
    public String chat(String message) {
        //对话记忆的唯一标识
        String conversantId = UUID.randomUUID().toString();

        ChatResponse response = chatClient
                .prompt()
                .user("我想去杭州")
                .advisors(spec -> spec.param(CHAT_MEMORY_CONVERSATION_ID_KEY, conversantId)
                        .param(CHAT_MEMORY_RETRIEVE_SIZE_KEY, 10))
                .call()
                .chatResponse();
        String content = response.getResult().getOutput().getText();
//        Assertions.assertNotNull(content);

        logger.info("content: {}", content);

        response = chatClient
                .prompt()
                .user("可以帮我推荐一些美食吗")
                .advisors(spec -> spec.param(CHAT_MEMORY_CONVERSATION_ID_KEY, conversantId)
                        .param(CHAT_MEMORY_RETRIEVE_SIZE_KEY, 10))
                .call()
                .chatResponse();
        content = response.getResult().getOutput().getText();
//        Assertions.assertNotNull(content);

        logger.info("content: {}", content);
        return content;
    }
}
